﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Configuration;

namespace NetworkSimulator
{
    public class RequestDispatcher:ITickerListener
    {
        private static RequestDispatcher singleTonObject;
        private Topology topology;
        private List<Request> requestList;
        private Config config = Config.instance();
        private Ticker ticker;
        private int numOfRequest;

        public int NumOfRequest
        {
            get { return numOfRequest; }
        }

        public static RequestDispatcher instance()
        {
            if (singleTonObject == null)
                singleTonObject = new RequestDispatcher();
            return singleTonObject;
        }

        public RequestDispatcher()
        {
            this.topology = Topology.instance();
            ticker = Ticker.instance();
            ticker.addListener(this);            
            loadRequestData();
            ticker.start();
        }

        public void loadRequestData()
        {
            FileStream file = new FileStream(config.RequestFilePath, FileMode.Open);
            StreamReader reader = new StreamReader(file);

            requestList = new List<Request>();

            while (!reader.EndOfStream)
            {
                string[] value = reader.ReadLine().Split('\t');
                Request package = makeReques(value);
                requestList.Add(package);
            }
            reader.Close();
            numOfRequest = requestList.Count;
            requestList = requestList.OrderBy(o => o.IncomingTime).ToList();
        }

        public Request makeReques(string[] value)
        {
            int id = int.Parse(value[0]);
            int source = int.Parse(value[1]);
            int destination = int.Parse(value[2]);
            double banwidth = double.Parse(value[3]);
            long incomingTime = long.Parse(value[4]);
            long holdingTime = long.Parse(value[5]);

            return new Request(id, source, destination, banwidth, incomingTime, holdingTime);
        }

        public void onTickerTick()
        {
            if (requestList.Count > 0)
            {
                Request request = requestList[0];
                while (request.IncomingTime <= ticker.ElapsedTime)
                {
                    topology.Nodes[request.Source].recieveRequest(request);
                    requestList.RemoveAt(0);
                    if (requestList.Count == 0) break;
                    request = requestList[0];
                }
            }
        }
    }
}
